package com.whynot.frame.basic.mybatis.service;

import com.baomidou.mybatisplus.entity.TableFieldInfo;
import com.baomidou.mybatisplus.entity.TableInfo;
import com.baomidou.mybatisplus.mapper.BaseMapper;
import com.baomidou.mybatisplus.mapper.Condition;
import com.baomidou.mybatisplus.plugins.Page;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.baomidou.mybatisplus.toolkit.ReflectionKit;
import com.baomidou.mybatisplus.toolkit.TableInfoHelper;
import com.google.common.collect.Lists;
import com.itextpdf.text.pdf.parser.LineSegment;
import com.whynot.frame.basic.common.model.APIBase;
import com.whynot.frame.basic.mybatis.conroller.model.BaseField;
import com.whynot.frame.basic.mybatis.model.BaseModel;
import com.whynot.frame.basic.util.Reflections;
import com.whynot.frame.basic.util.StringUtils;
import org.apache.commons.beanutils.BeanUtils;

import java.lang.reflect.InvocationTargetException;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 描    述:基础的Service接口
 * 创建时间: 2018/07/10
 */
public class BaseServiceImpl<M extends BaseMapper<T>, T extends BaseModel>  extends ServiceImpl<M, T> {
    /**
     * 组装Page
     * @param p
     * @param t
     * @return
     * @throws Exception
     */
    public com.baomidou.mybatisplus.plugins.Page<T> getPageCollection(com.whynot.frame.basic.mybatis.conroller.model.Page p, T t) throws Exception {
        Integer limit = p.getPageSize();
        // 开始索引
        Integer start = p.getCurrentPage();
        // 开始分页查询
        com.baomidou.mybatisplus.plugins.Page<T> page = new com.baomidou.mybatisplus.plugins.Page<T>(start,limit);
        Condition condition=Condition.create();
        //获取全部的字段，排除参数中不属于字段的参数
        TableInfo tableInfo = TableInfoHelper.getTableInfo(ReflectionKit.getSuperClassGenricType(getClass(), 1));
        List<TableFieldInfo> fields=tableInfo.getFieldList();
        //支持字段名和属性名查询
        Map<String,String> fieldMap=fields.stream().collect(Collectors.toMap(TableFieldInfo::getProperty, TableFieldInfo::getColumn));
        String[] fieldArr = Reflections.getClassFields(ReflectionKit.getSuperClassGenricType(getClass(), 1));
        for (String key :fieldArr) {
            String paramVal = BeanUtils.getProperty(t,key);
            String column=fieldMap.get(key);
            if (com.baomidou.mybatisplus.toolkit.StringUtils.isNotEmpty(paramVal)&& com.baomidou.mybatisplus.toolkit.StringUtils.isNotEmpty(column)) {
                condition.like(column, paramVal);
            }else if(com.baomidou.mybatisplus.toolkit.StringUtils.isNotEmpty(paramVal)&&fieldMap.values().contains(key)){
                condition.like(key, paramVal);
            }
        }
        this.setListSort(t,condition);
        com.baomidou.mybatisplus.plugins.Page result = this.getShowList(page,t);
        if(StringUtils.isNotEmpty(result)){
            return result;
        }
        return this.selectPage(page,condition);
    }

    /**
     * 设置排序
     * @param t
     * @param condition
     */
    public void  setListSort(T t,Condition condition){
        Collection collection = Lists.newArrayList();
        collection.add(BaseField.TABLE_DESC);
        condition.orderDesc(collection);
    }

    /***
     * 自定义分页
     * @param page
     * @param t
     * @return
     */
    public com.baomidou.mybatisplus.plugins.Page getShowList(com.baomidou.mybatisplus.plugins.Page page, T t) {
        return null;
    }

    /**
     *  list数据返回之前做处理
     * @param result
     */
    public void afterShowList(APIBase result) {
    }

    /**
     * 在保存之前对对象做处理
     * @param entity
     * @param t
     * @param <T>
     */
    public <T extends BaseModel> void beforeSaveUpdate(T entity, T t) {
    }

    /**
     * 在保存之后对对象做处理，可以设置其他关联对象
     * @param entity
     * @param t
     * @param <T>
     */
    public <T extends BaseModel> void afterSaveUpdate(T entity, T t) {
    }

    /**
     * 删除之后
     * @param id
     */
    public void afetrDelete(Integer id) {
    }

    /**
     * 对象修改之前的对对象做处理
     * @param entity
     * @param <T>
     */
    public <T extends BaseModel> void beforeShowUpdate(T entity) {
    }
}